package com.apes.fn.scm.internal.help.service;

import com.apes.fn.scm.internal.help.model.InternalHelpReturnApproval;
import com.apes.fn.scm.internal.help.model.InternalHelpReturnApprovalItem;
import com.apes.fn.scm.internal.help.repository.InternalHelpReturnApprovalRepository;
import com.apes.framework.jpa.spec.JpaDsl;
import com.apes.framework.plugin.esb.api.SimpleRequest;
import com.apes.framework.util.EventUtil;
import com.apes.framework.util.LogicalUtil;
import com.apes.scm.masterdata.enumeration.model.Enumeration;
import com.apes.scm.stock.transfer.model.Pick;
import com.apes.scm.stock.transfer.model.PickItem;
import com.apes.scm.stock.transfer.repository.PickRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.HashSet;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * 内协退货流转生成交货单：
 * <ul>
 *  <li>门店发货的交货单</li>
 *  <li>基地收货的交货单</li>
 * </ul>
 */
@Service
public class InternalHelpReturnFlowPickService {

    @Autowired
    private InternalHelpReturnApprovalRepository internalHelpReturnApprovalRepository;
    @Autowired
    private PickRepository pickRepository;

    /**
     * 门店发货的交货单
     *
     * <p> 创建內协退货发货单 </p>
     *
     * @param request InternalHelpReturnApproval
     * @return Pick
     */
    private Pick createPickOrder(SimpleRequest request) {
        InternalHelpReturnApproval approval = request.getO(InternalHelpReturnApproval.class);
        approval = internalHelpReturnApprovalRepository.findOne(approval.getId());

        // 判断所有商品是否全部为服务商品（非库存类商品）
        double count = approval.getApprovalItems().stream().filter(orderItem -> "aut".equals(orderItem.getProduct().getType())).count();
        if (count == approval.getApprovalItems().size()) {
            // 全部为服务商品就不需要发货，自动发货
            approval.setState("receipt");
            internalHelpReturnApprovalRepository.saveAndFlush(approval);    // 没有实物商品就自动收获
            return null;
        }

        //创建拣配单
        Pick pick = new Pick();
        Enumeration enumeration = new Enumeration();
        enumeration.setId("one");
        //一次性交货
        pick.setMoveType(enumeration);
        pick.setPartner(approval.getReceiptLocation().getCompany());
        pick.setLocation(approval.getShipLocation());
        // 公司为库区的公司
        pick.setCompany(approval.getCompany());

        pick.setOrigin(approval.getId());
        pick.setOriginBusinessType(approval.getInnerBusinessType());
        // 交货类型： 交货
        pick.setOperation("deliver");
        // 注入场景
        pick.setScene(approval.getScene());
        pick.setPickItems(getPickItem(approval));
        // 创建交货单
        EventUtil.sendSynEvent(this, "event:stock.pick.save", pick);

        // 回写状态
        if (approval.getState().equals("approve")) {
            approval.setState("delivered");
            internalHelpReturnApprovalRepository.saveAndFlush(approval);
        }
        return pick;
    }


    /**
     * 功能：获取明细数据
     *
     * @param approval
     * @return
     */
    private Set<PickItem> getPickItem(InternalHelpReturnApproval approval) {
        Set<PickItem> pickItems = approval.getApprovalItems().stream().filter(item -> LogicalUtil.notIn(item.getProduct().getType(), "aut")).map(
                (InternalHelpReturnApprovalItem item) -> {
                    PickItem pickItem = new PickItem();
                    pickItem.setProduct(item.getProduct());
                    pickItem.setUom(item.getUom());
                    pickItem.setOrderedQty(item.getProductReturnQty());
                    pickItem.setProductUomQty(item.getProductReturnQty());
                    pickItem.setOriginLine(item.getId());
                    return pickItem;
                }).collect(Collectors.toSet());
        return pickItems;
    }

    /**
     * 基地的收货单
     * <p>
     * 功能：创建收货方的交货单
     *
     * @param request InternalHelpReturnApproval
     * @return Pick 基地的收货单 Pick
     */
    private Pick createReceiptPick(SimpleRequest request) {
        InternalHelpReturnApproval approval = request.getO(InternalHelpReturnApproval.class);
        approval = internalHelpReturnApprovalRepository.findOne(approval.getId());

        long size = approval.getApprovalItems().stream().filter(orderItem -> LogicalUtil.in(orderItem.getProduct().getType(), "aut")).count();
        if (size == approval.getApprovalItems().size()) return null;  // 没有实物商品就返回

        Pick deliverPick = pickRepository.findOne(JpaDsl.toCriteriaByEq("origin", approval.getId(), "operation", "deliver"))
                .orElseThrow(() -> new RuntimeException("未找到交货单"));

        Pick pick = new Pick();
        pick.setAuto(false);     // 不自动收货

        Enumeration enumeration = new Enumeration();
        enumeration.setId("one");
        pick.setMoveType(enumeration);       // 交货方式 direct：部分交货，one： 一次性交货

        pick.setState("confirmed"); // 设置状态
        pick.setOperation("receipt");   // 交货类型：收货
        pick.setScene(approval.getScene());  // 注入场景

        pick.setCompany(approval.getReceiptLocation().getCompany());    // 设置公司
        pick.setLocation(approval.getReceiptLocation());    // 设置仓库
        pick.setPartner(approval.getShipLocation().getCompany());    // 合作伙伴 发货方的公司

        pick.setOrigin(approval.getId());
        pick.setOriginBusinessType(approval.getInnerBusinessType());

        // 明细数据，使用交货单的数量作为收货方的收货数量
        Set<PickItem> pickItems = new HashSet<>();
        for (PickItem deliverPickItem : deliverPick.getPickItems()) {
            long result = approval.getApprovalItems().stream()
                    .filter(item -> item.getId().equals(deliverPickItem.getOriginLine()))
                    .map(approvalItem -> {
                        double qtyDone = ((Number) deliverPickItem.getQtyDone()).doubleValue();
                        PickItem pickItem = new PickItem();
                        // 获取数量
                        pickItem.setOrderedQty(qtyDone);
                        pickItem.setProduct(approvalItem.getProduct());
                        pickItem.setUom(approvalItem.getUom());
                        pickItem.setProductUomQty(approvalItem.getProductReturnQty());
                        pickItem.setOriginLine(String.valueOf(approvalItem.getId()));

                        pickItems.add(pickItem);
                        return approvalItem;
                    }).count();
            if (result != 1) {
                throw new RuntimeException("內协退货单行号：" + deliverPickItem.getOriginLine() + " 输入错误！");
            }
        }
        pick.setPickItems(pickItems);
        // 创建交货单
        EventUtil.sendSynEvent(this, "event:stock.pick.save", pick);
        return pick;
    }
}
